package com.jeeplus.modules.statistics.service;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import com.jeeplus.common.utils.CalculateUtil;
import com.jeeplus.common.utils.RedisUtils;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.common.utils.collection.CollectionUtil;
import com.jeeplus.common.web.Result;
import com.jeeplus.database.datasource.annotation.DS;
import com.jeeplus.modules.statistics.model.constant.Constant;
import com.jeeplus.modules.statistics.mapper.AreaCountMapper;
import com.jeeplus.modules.statistics.model.domain.AreaCount;
import com.jeeplus.modules.statistics.model.query.IndexStatisticsQuery;
import com.jeeplus.modules.statistics.model.vo.BusinessRanking;
import com.jeeplus.modules.statistics.model.vo.StatisticsXY;
import com.jeeplus.modules.statistics.model.vo.YearRankingVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName: IndexService
 * Function:  首页
 * Date:      2021/3/11 10:53
 *
 * @author hanKongbin
 * version    V1.0
 */
@DS("queuing")
@Service
@Slf4j
@RequiredArgsConstructor
public class IndexService {

    private final AreaCountMapper areaCountMapper;

    private final RedisUtils redisUtils;

    @Value("${statistics.cache.expiretime.ranking}")
    private long expireTime;

    @Value("${statistics.indexShowAreaPid}")
    private String indexShowAreaPid;


    /**
     * 当日排名
     *
     * @param query
     * @return
     */
    public Result<StatisticsXY> todayRanking(IndexStatisticsQuery query) {
        if (StringUtils.isEmpty(query.getYear())) {
            return Result.failed(HttpStatus.SC_INTERNAL_SERVER_ERROR, "参数非法！");
        }
        List<String> xValue = new ArrayList<>();
        List<Long> yValue = new ArrayList<>();
        try {
            String key = Constant.INDEX_TODAY_RANKING + query.getYear();
            if (redisUtils.hasKey(key)) {
                return Result.succeed(JSON.parseObject(redisUtils.get(key).toString(), StatisticsXY.class), "获取成功！");
            }
            List<AreaCount> areaCounts = areaCountMapper.todayRanking(query);
            // 合并分中心、社区
            areaCounts = mergeArea(areaCounts, false);
            for (AreaCount areaCount : areaCounts) {
                xValue.add(areaCount.getName());
                yValue.add(areaCount.getNumber());
            }
            redisUtils.set(key, JSON.toJSONString(new StatisticsXY(xValue, yValue)), expireTime);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取今日排名失败！");
        }
        return Result.succeed(new StatisticsXY(xValue, yValue), "获取成功！");
    }

    /**
     * 月排行
     *
     * @param query
     * @return
     */
    public Result<StatisticsXY> monthRanking(IndexStatisticsQuery query) {
        if (StringUtils.isEmpty(query.getYear())) {
            return Result.failed(HttpStatus.SC_INTERNAL_SERVER_ERROR, "参数非法！");
        }
        List<String> xValue = new ArrayList<>();
        List<StatisticsXY.StatisticsND> yValue = new ArrayList<>();
        try {
            String key = Constant.INDEX_MONTH_RANKING + query.getYear();
            if (redisUtils.hasKey(key)) {
                return Result.succeed(JSON.parseObject(redisUtils.get(key).toString(), StatisticsXY.class), "获取成功！");
            }
            List<AreaCount> areaCounts = areaCountMapper.monthRanking(query);
            // 合并分中心、社区
            areaCounts = mergeArea(areaCounts, true);
            Map<String, List<AreaCount>> areaCountsMap = areaCounts.stream().collect(Collectors.groupingBy(AreaCount::getName));
            long[] yTotalData = new long[12];
            for (Map.Entry<String, List<AreaCount>> entry : areaCountsMap.entrySet()) {
                // 12个月份对应的数值
                long[] yData = new long[12];
                for (AreaCount obj : entry.getValue()) {
                    if (null == obj.getMonth() || obj.getMonth() > yData.length) {
                        continue;
                    }
                    yData[obj.getMonth() - 1] = obj.getNumber();
                    long total = yTotalData[obj.getMonth() - 1];
                    yTotalData[obj.getMonth() - 1] = (total + obj.getNumber());
                }
                xValue.add(entry.getKey());
                yValue.add(new StatisticsXY.StatisticsND(entry.getKey(), yData));
            }
            xValue.add("总接件量");
            yValue.add(new StatisticsXY.StatisticsND("总接件量", yTotalData));
            redisUtils.set(key, JSON.toJSONString(new StatisticsXY(xValue, yValue)), expireTime);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取月排名失败！");
        }
        return Result.succeed(new StatisticsXY(xValue, yValue), "获取成功！");
    }


    /**
     * 总接件排行
     *
     * @param query
     * @return
     */
    public Result<List<YearRankingVO>> yearRanking(IndexStatisticsQuery query) {
        if (StringUtils.isEmpty(query.getYear())) {
            return Result.failed(HttpStatus.SC_INTERNAL_SERVER_ERROR, "参数非法！");
        }
        List<YearRankingVO> data = new ArrayList<>();
        long count = 0L;
        try {
//            String key = Constant.INDEX_TOTAL_RANKING + query.getYear();
//            if (redisUtils.hasKey(key)) {
//                data = JSON.parseArray(redisUtils.get(key).toString(), YearRankingVO.class);
//                count = data.stream().mapToLong(YearRankingVO::getValue).sum();
//                return Result.succeed(data, "获取成功！", ImmutableMap.of(Constant.AJAX_JSON_COUNT, count));
//            }
            List<AreaCount> areaCounts = areaCountMapper.yearRanking(query);
            // 合并分中心、社区
            areaCounts = mergeArea(areaCounts, false);
            count = areaCounts.stream().mapToLong(AreaCount::getNumber).sum();
            long finalCount = count;
            data = areaCounts.stream().map(e ->
                    YearRankingVO.builder()
                            .areaNo(e.getId())
                            .value(e.getNumber())
                            .label(e.getName())
                            .fullName(e.getFullName())
                            .type(e.getType())
                            .latitude(e.getLatitude())
                            .longitude(e.getLongitude())
                            .address(e.getAddress())
                            .percent(CalculateUtil.calculatePercent(new BigDecimal(e.getNumber()), new BigDecimal(finalCount), 0))
                            .build()).collect(Collectors.toList());
            //redisUtils.set(key, JSON.toJSONString(data), expireTime);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取年排名失败！");
        }
        query.setYear("%"+query.getYear()+"%");
        List <HashMap <String, String>> map = areaCountMapper.sumCountBJ(query);
        for(YearRankingVO yr : data){
            for(HashMap <String, String> maps : map){
                if(yr.getAreaNo().equals(maps.get("areaId"))){
                    yr.setValue(yr.getValue()+Integer.parseInt(String.valueOf(maps.get("num"))));
                    count+=Integer.parseInt(String.valueOf(maps.get("num")));
                }
            }
        }
        return Result.succeed(data, "获取成功！", ImmutableMap.of(Constant.AJAX_JSON_COUNT, count));
    }


    /**
     * 热度业务排名
     *
     * @param query
     * @return
     */
    public Result<List<BusinessRanking>> businessRanking(IndexStatisticsQuery query) {
        List<BusinessRanking> data = new ArrayList<>();
        List<String> areaPids = Arrays.asList(indexShowAreaPid.split(","));
        try {
            String key = Constant.INDEX_BUSINESS_RANKING + query.getYear();
            if (redisUtils.hasKey(key)) {
                return Result.succeed(JSON.parseArray(redisUtils.get(key).toString(), BusinessRanking.class), "获取成功！");
            }
            List<AreaCount> areaCounts = areaCountMapper.businessRanking(query);
            areaCounts = areaCounts.stream().filter(e ->areaPids.contains(e.getPId())).collect(Collectors.toList());
            Map<String, List<AreaCount>> areaCountsMap = areaCounts.stream().collect(Collectors.groupingBy(AreaCount::getName));
            for (Map.Entry<String, List<AreaCount>> entry : areaCountsMap.entrySet()) {
                BusinessRanking businessRanking = new BusinessRanking();
                businessRanking.setAreaName(entry.getKey());
                entry.getValue().stream().max(Comparator.comparing(AreaCount::getNumber)).ifPresent(e -> {
                    businessRanking.setBusName(e.getBusinessId());
                    businessRanking.setFullName(e.getFullName());
                    businessRanking.setType(e.getType());
                });
                data.add(businessRanking);
            }
            redisUtils.set(key, JSON.toJSONString(data), expireTime);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取热度业务排名失败！");
        }
        return Result.succeed(data, "获取成功！");
    }


    public Result<Long> total(IndexStatisticsQuery query) {
        return Result.succeed(areaCountMapper.total(query), "获取成功！");
    }


    /**
     * 合并区域并汇总
     * 1、街道分中心和社区的数据汇总到街道
     * 2、只保留区级中心和街道
     *
     * @param areaCounts
     * @param monthRanking 是否月排;如果为月排行榜统计，父级合并子级数据时，需要判断月份是否相同。
     * @return
     */
    private List<AreaCount> mergeArea(List<AreaCount> areaCounts, boolean monthRanking) {
        List<String> areaPIds = Arrays.asList(indexShowAreaPid.split(","));
        if (CollectionUtil.isEmpty(areaCounts) || CollectionUtil.isEmpty(areaPIds)) {
            return new ArrayList<>();
        }
        // 筛选出父级区域（主目录、区级、街道）
        List<AreaCount> parentArea = areaCounts.stream().filter(e -> areaPIds.contains(e.getPId())).collect(Collectors.toList());
        // 筛选出子级区域 街道分中心、社区
        List<AreaCount> childArea = areaCounts.stream().filter(e -> !areaPIds.contains(e.getPId())).collect(Collectors.toList());
        for (AreaCount p : parentArea) {
            // 父级合并对应的子级接件量
            List<AreaCount> pc;
            if (monthRanking) {
                pc = childArea.stream().filter(e -> e.getPId().equals(p.getId()) && null != e.getMonth() && null != p.getMonth() && e.getMonth().equals(p.getMonth())).collect(Collectors.toList());
            } else {
                pc = childArea.stream().filter(e -> e.getPId().equals(p.getId())).collect(Collectors.toList());
            }
            // 子级数量汇总
            long number = pc.stream().mapToLong(AreaCount::getNumber).sum();
            p.setNumber(p.getNumber() + number);
        }
        // 降序排序
        return parentArea.stream().sorted(Comparator.comparing(AreaCount::getNumber).reversed()).collect(Collectors.toList());
    }
}